using System.Reflection;
using System.Data.SqlClient;
namespace Gl.SettingsManager
{
	internal delegate void ExecuteCommandDelegate(SqlCommand command,
		params object[] objects);

	internal class Utils
	{
		internal static T GetAttribute<T>(ICustomAttributeProvider attributeProvider)
		{
			T[] attrs = GetAttributes<T>(attributeProvider);
			return attrs.Length > 0 ? attrs[0] : default(T);
		}

		internal static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider)
		{
			object[] attributes = attributeProvider.GetCustomAttributes(typeof(T), false);
			T[] ts = new T[attributes.Length];
			for (int i = 0; i < attributes.Length; ++i)
				ts[i] = (T)attributes[i];
			return ts;
		}

		internal static bool HasGetter(PropertyInfo info)
		{
			if (info.GetGetMethod() == null && info.GetGetMethod(true) == null)
				return false;
			else
				return true;
		}

		internal static bool HasSetter(PropertyInfo info)
		{
			if (info.GetSetMethod() == null && info.GetSetMethod(true) == null)
				return false;
			else
				return true;
		}

		internal static bool IsIndexer(PropertyInfo info)
		{
			MethodInfo minfo = info.GetGetMethod() == null ? info.GetGetMethod(true) : info.GetGetMethod();
			if (minfo.GetParameters().Length > 0)
				return true;
			else
				return false;
		}

		internal static string GetContextName(object obj)
		{
			if (obj is ISettingsContext)
				return (obj as ISettingsContext).ContextName;
			else
				return string.Empty;
		}

		internal static void ExecuteCommand(string connection, bool useTransaction, 
			ExecuteCommandDelegate procedure, params object[] objects)
		{
			using (SqlConnection conn = new SqlConnection(connection))
			{
				conn.Open();
				using (SqlCommand cmd = new SqlCommand())
				{
					cmd.Connection = conn;
					if (useTransaction)
					{
						SqlTransaction trans = conn.BeginTransaction();
						try
						{
							cmd.Transaction = trans;
							procedure(cmd, objects);
							trans.Commit();
						}
						catch
						{
							trans.Rollback();
							throw;
						}
					}
					else
					{
						procedure(cmd, objects);
					}
					
				}
			}
		}
	}
}
